﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Xml;
using System.IO;

namespace WQ.Common
{


        //    /**//// <summary>
        //    /// XML转化为Model的方法
        //    /// </summary>
        //    /// <param name="xml">要转化的XML</param>
        //    /// <param name="SampleModel">Model的实体示例，New一个出来即可</param>
        //    /// <returns></returns>
        //    public static object ConvertModel(string xml, object SampleModel)
        //    {
        //        if (string.IsNullOrEmpty(xml))
        //            return SampleModel;
        //        else
        //        {
        //            XmlDocument xmldoc = new XmlDocument();
        //            xmldoc.LoadXml(xml);

        //            XmlNodeList attributes = xmldoc.SelectSingleNode("Model").ChildNodes;
        //            foreach (XmlNode node in attributes)
        //            {
        //                foreach (PropertyInfo property in SampleModel.GetType().GetProperties())
        //                {
        //  if (node.Name == property.Name)
        //  {
        //   if (node.InnerText != "[Null]")
        //   {
        //    if (property.PropertyType == typeof(System.Guid))
        //     property.SetValue(SampleModel, new Guid(node.InnerText), null);
        //    else
        //     property.SetValue(SampleModel, Convert.ChangeType(node.InnerText, property.PropertyType), null);
        //   }
        //   else
        //    property.SetValue(SampleModel, null, null);
        //  }
        //                }
        //            }
        //            return SampleModel;
        //        }
        //    }
        //    #endregion

    /// <summary>
     /// 实体转Xml，Xml转实体类
     /// </summary>
     /// <typeparam name="T"></typeparam>
     public class XmlHelper<T> where T : new()
     {
         #region 实体类转成Xml
         /// <summary>
         /// 对象实例转成xml
         /// </summary>
         /// <param name="item">对象实例</param>
         /// <returns></returns>
         public static string EntityToXml(T item)
         {
             IList<T> items = new List<T>();
             items.Add(item);
             return EntityToXml(items);
         }
 
         /// <summary>
         /// 对象实例集转成xml
         /// </summary>
         /// <param name="items">对象实例集</param>
         /// <returns></returns>
         public static string EntityToXml(IList<T> items)
         {
             //创建XmlDocument文档
             XmlDocument doc = new XmlDocument();
             doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null));

             //创建根元素
             XmlElement root = doc.CreateElement(typeof(T).Name + "s");
             //添加根元素的子元素集
             foreach (T item in items)
             {
                 EntityToXml(doc, root, item);
             }
             //向XmlDocument文档添加根元素
             doc.AppendChild(root);
             
             return doc.InnerXml;
         }
 
         private static void EntityToXml(XmlDocument doc, XmlElement root, T item)
         {
             //创建元素
             XmlElement xmlItem = doc.CreateElement(typeof(T).Name);
             //对象的属性集
             System.Reflection.PropertyInfo[] propertyInfo = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
 
             foreach (System.Reflection.PropertyInfo pinfo in propertyInfo)
             {
                 if (pinfo != null)
                 {
                     //对象属性名称
                     string name = pinfo.Name;
                     //对象属性值
                     string value = String.Empty;
                     
                     if (pinfo.GetValue(item, null) != null)
                         value = pinfo.GetValue(item, null).ToString();//获取对象属性值
                     //设置元素的属性值
                     xmlItem.SetAttribute(name,value);
                 }
             }
             //向根添加子元素
             root.AppendChild(xmlItem);
         }
 
        
         #endregion
 
         #region Xml转成实体类
 
         /// <summary>
         /// Xml转成对象实例
         /// </summary>
         /// <param name="xml">xml</param>
         /// <returns></returns>
         public static T XmlToEntity(string xml)
         {
            IList<T> items= XmlToEntityList(xml);
            if (items != null && items.Count > 0)
                return items[0];
            else return default(T);
         }
 
         /// <summary>
         /// Xml转成对象实例集
         /// </summary>
         /// <param name="xml">xml</param>
         /// <returns></returns>
         public static IList<T> XmlToEntityList(string xml)
         {
             XmlDocument doc = new XmlDocument();
             try
             {
                 doc.LoadXml(xml);
             }
             catch
             {
                 return null;
             }
             if (doc.ChildNodes.Count != 1)
                 return null;
             if (doc.ChildNodes[0].Name.ToLower() != typeof(T).Name.ToLower() + "s")
                 return null;
 
             XmlNode node = doc.ChildNodes[0];
 
             IList<T> items = new List<T>();
 
             foreach (XmlNode child in node.ChildNodes)
             {
                 if (child.Name.ToLower() == typeof(T).Name.ToLower())
                     items.Add(XmlNodeToEntity(child));
             }
 
             return items;
         }
 
         private static T XmlNodeToEntity(XmlNode node) 
         {
             T item = new T();
 
             if (node.NodeType == XmlNodeType.Element)
             {
                 XmlElement element = (XmlElement)node;
 
                 System.Reflection.PropertyInfo[] propertyInfo = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
 
                 foreach (XmlAttribute attr in element.Attributes)
                 {
                     string attrName = attr.Name.ToLower();
                     string attrValue = attr.Value.ToString();
                     foreach (System.Reflection.PropertyInfo pinfo in propertyInfo)
                     {
                         if (pinfo != null)
                         {
                             string name = pinfo.Name.ToLower();
                             Type dbType = pinfo.PropertyType;
                             if (name == attrName)
                             {
                                 if (String.IsNullOrEmpty(attrValue))
                                     continue;
                                 switch (dbType.ToString())
                                 {
                                     case "System.Int32":
                                         pinfo.SetValue(item, Convert.ToInt32(attrValue), null);
                                         break;
                                     case "System.Boolean":
                                         pinfo.SetValue(item, Convert.ToBoolean(attrValue), null);
                                         break;
                                     case "System.DateTime": 
                                         pinfo.SetValue(item, Convert.ToDateTime(attrValue), null);
                                         break;
                                     case "System.Decimal":
                                         pinfo.SetValue(item, Convert.ToDecimal(attrValue), null);
                                         break;
                                     case "System.Double":
                                         pinfo.SetValue(item, Convert.ToDouble(attrValue), null);
                                         break;
                                     default:
                                         pinfo.SetValue(item, attrValue, null);
                                         break;
                                 }
                                 continue;
                             }
                         }
                     }
                 }
             }
             return item;
         }
 
         #endregion

    }
}
